'use strict'

const fs = require('fs');
const sqlite3 = require('sqlite3').verbose();

const util = require('./util');
const config = require('./config');

const logger = util.logger;
const db = new sqlite3.Database(config.db3);

const defaultAuth = ['about', '杂项', '第三方技术'];
const BOOK_PATH = './public/docs/';
const ADD_USER = 'insert into users (user, psw, name) values ($user, $psw, $name)';
const UPDATE_USER = 'update users set psw=$psw, name=$name, auth=$auth where user=$user';
const DEL_USER = 'delete from users where user=$user';
const GET_USER = 'select * from users where user=$user';
const ALL_USER = 'select * from users order by user';

let userAuth = {};    //保存用户的权限信息,key为签名后的token,value为auth数组

const runSql = (sql, param, isQuery) => {
  return new Promise((suc, fail) => {
    try{
      db.serialize(() => {
        if (isQuery){
          db.all(sql, param, function(err, data) {
            logger.debug('query data: ', data);
            if (err) {
              logger.warn('run sql error:', err);
              fail(err);
            }else{
              suc(data);
            }
          });
        }else{
          db.run(sql,param, function(err, data) {
            logger.debug('update data: ', data);
            if (err) {
              logger.warn('run sql error:', err);
              fail(err);
            }else{
              suc(data);
            }
          })
        }
      });
    }catch(e){
      fail(e);
    }
  });
}

const allUser = async () => {
  let list = await runSql(ALL_USER, undefined, true);
  for (let v of list) {
    v.auth = v.auth ? v.auth.split(',') : []
  }
  return list;
}

const addUser = async (user) => {
  await runSql(ADD_USER, {
    $user: user.user,
    $psw: user.psw,
    $name: user.name
  });
  await loadToken();
}

const delUser = async (user) => {
  await runSql(DEL_USER, {
    $user: user.user
  });
  await loadToken();
}

const updateUser = async (user) => {
  await runSql(UPDATE_USER, {
    $user: user.user,
    $psw: user.psw,
    $name: user.name,
    $auth: typeof (user.auth) === 'object' ? user.auth.join(',') : user.auth
  });
  await loadToken();
}

const getUser = async (user) => {
  let result = await runSql(GET_USER, { $user: user.user }, true);
  if (result){
    result[0].auth = result[0].auth ? result[0].auth.split(',') : []
    return result[0]
  }else{
    return {}
  }
}

const loadToken = async () => {
  let list = await allUser();
  let token = {};
  for (let u of list) {
    token[util.signUser(u)] = u.auth;
  }
  userAuth = token;
}

const getAuth = (token) => {
  return userAuth[token]
}

const checkToken = (token) => {
  logger.debug('user token : %s', token);
  if (token) {
    let auth = getAuth(token);
    logger.debug('user auth : ', auth)
    return auth;
  }else{
    return undefined;
  }
}

 
//从目录结构中加载用户访问权限,返回内容数组
const loadAuth = () => {
  let projects = {};
  if (fs.existsSync(BOOK_PATH)){
    let docs = fs.readdirSync(BOOK_PATH);   //docs 目录的内容:大类
    for(let dir of docs){
      if (defaultAuth.indexOf(dir) === -1){   //默认目录不算做权限
        projects[dir] = [];     //保存每个大类中的项目名
        let pros = fs.readdirSync(BOOK_PATH + '/' + dir);
        for(let pro of pros){
          projects[dir].push(pro);    //每个大类下的项目名
        }
      }
    }
  }
  logger.debug('读取到目录结构: ', projects);
  return projects;
}
//运行时加载权限
loadToken();

module.exports = {
  db, defaultAuth, allUser, getUser, addUser, updateUser, delUser, getAuth, checkToken, loadAuth
}